package util

import (
"fmt"
"regexp"
"strings"
"unicode"
"unicode/utf8"
)

var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")

// 驼峰转换为下划线
func ToSnakeCase(str string, toLower bool) string {
	snake := matchAllCap.ReplaceAllString(matchFirstCap.ReplaceAllString(str, "${1}_${2}"), "${1}_${2}")

	if toLower {
		return strings.ToLower(snake)
	}

	return snake
}

// 首字母大写
func Ucfirst(s string) string {
	return strings.ToUpper(s[:1]) + s[1:]
}

// 首字母小写
func LcFirst(n string) string {
	return strings.ToLower(n[:1]) + n[1:]
}

func Substr(str string, start uint, length int) string {
	if start < 0 || length < -1 {
		return str
	}
	switch {
	case length == -1:
		return str[start:]
	case length == 0:
		return ""
	}
	end := int(start) + length
	if end > len(str) {
		end = len(str)
	}
	return str[start:end]
}

func Strrev(str string) string {
	runes := []rune(str)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func MbStrlen(str string) int {
	return utf8.RuneCountInString(str)
}

func Trim(s, cutset string) string {
	if cutset == "" {
		return strings.TrimSpace(s)
	}
	return strings.Trim(s, cutset)
}

func Ltrim(s, cutset string) string {

	return strings.TrimLeft(s, cutset)
}

func Rtrim(s, cutset string) string {

	return strings.TrimRight(s, cutset)
}

func Chr(ascii int) string {
	return string(ascii)
}

func Ord(char string) int {
	r, _ := utf8.DecodeRune([]byte(char))
	return int(r)
}

// 是否是中文字符
func IsChineseChar(str string) bool {

	for _, r := range str {
		if unicode.Is(unicode.Scripts["Han"], r) || (regexp.MustCompile("[\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b]").MatchString(string(r))) {
			return true
		}
	}
	return false
}

// 补充前导0
func CompleteZero(num, l int64) string {
	numstr := fmt.Sprint(num)
	cha := int(l) - len(numstr)

	var beforeStr string
	if cha > 0 {
		for i := 0; i < cha; i++ {
			beforeStr += "0"
		}
	}

	return beforeStr + numstr
}


func HasUpper(s string) bool {
	for _, c := range s {
		if unicode.IsUpper(c) {
			return true
		}
	}
	return false
}